﻿using MyAlbum.Services;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using System.Collections.Generic;
using System;
using System.Linq;
using MyAlbum.Model;
using PersonalAlbum.Exceptions;
namespace UnitTests
{


    /// <summary>
    ///This is a test class for SectionServiceTest and is intended
    ///to contain all SectionServiceTest Unit Tests
    ///</summary>
    [TestClass()]
    public class SectionServiceTest
    {


        private TestContext testContextInstance;

        /// <summary>
        ///Gets or sets the test context which provides
        ///information about and functionality for the current test run.
        ///</summary>
        public TestContext TestContext
        {
            get
            {
                return testContextInstance;
            }
            set
            {
                testContextInstance = value;
            }
        }

        #region Additional test attributes
        // 
        //You can use the following additional attributes as you write your tests:
        //
        //Use ClassInitialize to run code before running the first test in the class
        [ClassInitialize()]
        public static void MyClassInitialize(TestContext testContext)
        {

        }
        //
        //Use ClassCleanup to run code after all tests in a class have run
        //[ClassCleanup()]
        //public static void MyClassCleanup()
        //{
        //}
        //
        //Use TestInitialize to run code before running each test
        [TestInitialize()]
        public void MyTestInitialize()
        {
            _testConfig = new TestConfig();
            _testConfig.Initialize(PersistenceModes.Xml);
            sections = new List<MyAlbum.Model.Section>();
        }
        //
        //Use TestCleanup to run code after each test has run
        [TestCleanup()]
        public void MyTestCleanup()
        {
            foreach (var item in sections)
            {
                Service.DeleteItem(item);
            }
            _testConfig.Dispose();
        }
        //
        #endregion
        private TestConfig _testConfig;
        private List<MyAlbum.Model.Section> sections;
        MyAlbum.Services.SectionService Service
        {
            get
            {
                return ObjectFactory.GetInstance<IDataService<Section>>() as MyAlbum.Services.SectionService;
            }
        }

        /// <summary>
        ///A test for UpdateItem
        ///</summary>
        [TestMethod()]
        public void UpdateItemTest()
        {

            MyAlbum.Services.SectionService target = this.Service;
            var user = new GenericUser("tal", new string[] { "Admin" });
            ((TestUser)ObjectFactory.GetInstance<IUser>()).SetUser(user);
            MyAlbum.Model.Section item = new Section()
            {
                ContentUrl = Guid.NewGuid().ToString(),
                Name = Guid.NewGuid().ToString(),
                Description = Guid.NewGuid().ToString()
            };
            target.AddItem(item, new MyAlbum.Utility.GenericValidationSummary());
            this.sections.Add(item);
            item.Name = Guid.NewGuid().ToString();
            target.UpdateItem(item, new MyAlbum.Utility.GenericValidationSummary());
            var loaded = target.GetItemById(item.Id);
            Assert.IsNotNull(loaded);
            Compare(item, loaded);
        }

        [TestMethod()]
        public void UpdateItemTest_Un_Authorized_User()
        {

            MyAlbum.Services.SectionService target = this.Service;
            var user = new GenericUser("tal", new string[] { "Admin" });
            ((TestUser)ObjectFactory.GetInstance<IUser>()).SetUser(user);
            string name = Guid.NewGuid().ToString();
            MyAlbum.Model.Section item = new Section()
            {
                ContentUrl = Guid.NewGuid().ToString(),
                Name = name,
                Description = Guid.NewGuid().ToString(),
                Visible = true
            };
            target.AddItem(item, new MyAlbum.Utility.GenericValidationSummary());
            this.sections.Add(item);
            item.Name = Guid.NewGuid().ToString();
            user = new GenericUser("tal", new string[] { "User" });
            ((TestUser)ObjectFactory.GetInstance<IUser>()).SetUser(user);
            var v = new MyAlbum.Utility.GenericValidationSummary();
            target.UpdateItem(item, v);
            Assert.IsFalse(v.IsValid);
            var loaded = target.GetItemById(item.Id);
            Assert.IsNotNull(loaded);
            //check that wasn't updated
            Assert.AreEqual(name, loaded.Name);
        }

        /// <summary>
        ///A test for UpdateItem
        ///</summary>
        [TestMethod()]
        public void UpdateItem_Null_Name()
        {

            MyAlbum.Services.SectionService target = this.Service;
            var user = new GenericUser("tal", new string[] { "Admin" });
            ((TestUser)ObjectFactory.GetInstance<IUser>()).SetUser(user);
            string name = Guid.NewGuid().ToString();
            MyAlbum.Model.Section item = new Section()
            {
                ContentUrl = Guid.NewGuid().ToString(),
                Name = name,
                Description = Guid.NewGuid().ToString()
            };
            var v = new MyAlbum.Utility.GenericValidationSummary();
            target.AddItem(item, new MyAlbum.Utility.GenericValidationSummary());
            this.sections.Add(item);
            item.Name = null;
            target.UpdateItem(item, v);
            var loaded = target.GetItemById(item.Id);
            Assert.IsNotNull(loaded);
            Assert.IsFalse(v.IsValid);
            Assert.AreEqual("Name", v.Errors.Keys.First());
            //check that wasn't updated
            Assert.AreEqual(name, loaded.Name);

        }

        /// <summary>
        ///A test for UpdateItem
        ///</summary>
        [TestMethod()]
        public void UpdateItem_Empty_Name()
        {
            var user = new GenericUser("tal", new string[] { "Admin" });
            ((TestUser)ObjectFactory.GetInstance<IUser>()).SetUser(user);
            MyAlbum.Services.SectionService target = this.Service;
            string name = Guid.NewGuid().ToString();
            MyAlbum.Model.Section item = new Section()
            {
                ContentUrl = Guid.NewGuid().ToString(),
                Name = name,
                Description = Guid.NewGuid().ToString()
            };
            var v = new MyAlbum.Utility.GenericValidationSummary();
            target.AddItem(item, v);
            this.sections.Add(item);
            item.Name = "  ";
            v = new MyAlbum.Utility.GenericValidationSummary();
            target.UpdateItem(item, v);
            Assert.IsFalse(v.IsValid);
            Assert.AreEqual("Name", v.Errors.Keys.First());
            var loaded = target.GetItemById(item.Id);
            Assert.IsNotNull(loaded);
            //check that the item wasn't updated
            Assert.AreEqual(name, loaded.Name);
        }

        /// <summary>
        ///A test for UpdateItem
        ///</summary>
        [TestMethod()]
        [ExpectedException(typeof(AssertionException))]
        public void UpdateItem_Null_Item()
        {
            var user = new GenericUser("tal", new string[] { "Admin" });
            ((TestUser)ObjectFactory.GetInstance<IUser>()).SetUser(user);
            MyAlbum.Services.SectionService target = this.Service;
            target.UpdateItem(null, new MyAlbum.Utility.GenericValidationSummary());
        }

        private void Compare(Section expected, Section actual)
        {
            Assert.AreEqual(expected.ContentUrl, actual.ContentUrl);
            Assert.AreEqual(expected.Description, actual.Description);
            Assert.AreEqual(expected.DisplayOrder, actual.DisplayOrder);
            Assert.AreEqual(expected.Id, actual.Id);
            Assert.AreEqual(expected.Name, actual.Name);
            Assert.AreEqual(expected.Visible, actual.Visible);

        }

        /// <summary>
        ///A test for GetItems
        ///</summary>
        [TestMethod()]
        public void GetItemsTest_Not_Visible_Non_Admin()
        {
            var user = new GenericUser("tal", new string[] { "Admin" });
            ((TestUser)ObjectFactory.GetInstance<IUser>()).SetUser(user);
            MyAlbum.Services.SectionService target = this.Service;
            MyAlbum.Model.Section item = new Section()
            {
                ContentUrl = Guid.NewGuid().ToString(),
                Name = Guid.NewGuid().ToString(),
                Description = Guid.NewGuid().ToString()
            };
            target.AddItem(item, new MyAlbum.Utility.GenericValidationSummary());
            this.sections.Add(item);
            user = new GenericUser("tal", new string[] { "" });
            ((TestUser)ObjectFactory.GetInstance<IUser>()).SetUser(user);
            var actual = target.GetItems();
            Assert.IsNotNull(actual);
            var loaded = actual.SingleOrDefault(s => s.Id == item.Id);
            Assert.IsNull(loaded);
        }

        /// <summary>
        ///A test for GetItems
        ///</summary>
        [TestMethod()]
        public void GetItemsTest_Not_Visible_For_Admin()
        {
            var user = new GenericUser("tal", new string[] { "Admin" });
            ((TestUser)ObjectFactory.GetInstance<IUser>()).SetUser(user);
            MyAlbum.Services.SectionService target = this.Service;
            MyAlbum.Model.Section item = new Section()
            {
                ContentUrl = Guid.NewGuid().ToString(),
                Name = Guid.NewGuid().ToString(),
                Description = Guid.NewGuid().ToString()
            };
            target.AddItem(item, new MyAlbum.Utility.GenericValidationSummary());
            this.sections.Add(item);

            var actual = target.GetItems();
            Assert.IsNotNull(actual);
            var loaded = actual.SingleOrDefault(s => s.Id == item.Id);
            Assert.IsNotNull(loaded);
            Compare(item, loaded);
        }

        /// <summary>
        ///A test for GetItems
        ///</summary>
        [TestMethod()]
        public void GetItemsTest_Visible_Items()
        {
            var user = new GenericUser("tal", new string[] { "Admin" });
            ((TestUser)ObjectFactory.GetInstance<IUser>()).SetUser(user);
            MyAlbum.Services.SectionService target = this.Service;
            MyAlbum.Model.Section item = new Section()
            {
                ContentUrl = Guid.NewGuid().ToString(),
                Name = Guid.NewGuid().ToString(),
                Visible = true,
                Description = Guid.NewGuid().ToString()
            };
            target.AddItem(item, new MyAlbum.Utility.GenericValidationSummary());
            this.sections.Add(item);


            var actual = target.GetItems();
            Assert.IsNotNull(actual);
            var loaded = actual.SingleOrDefault(s => s.Id == item.Id);
            Assert.IsNotNull(loaded);
            Compare(item, loaded);
        }


        /// <summary>
        ///A test for GetItemById
        ///</summary>
        [TestMethod()]
        public void GetItemByIdTest()
        {
            var user = new GenericUser("tal", new string[] { "Admin" });
            ((TestUser)ObjectFactory.GetInstance<IUser>()).SetUser(user);
            MyAlbum.Services.SectionService target = this.Service;
            MyAlbum.Model.Section item = new Section()
            {
                ContentUrl = Guid.NewGuid().ToString(),
                Name = Guid.NewGuid().ToString(),
                Visible = true,
                Description = Guid.NewGuid().ToString()
            };
            target.AddItem(item, new MyAlbum.Utility.GenericValidationSummary());
            this.sections.Add(item);
            var loaded = target.GetItemById(item.Id);
            Assert.IsNotNull(loaded);
            Compare(item, loaded);
        }

        /// <summary>
        ///A test for GetItemById
        ///</summary>
        [TestMethod()]
        public void GetItemByIdTest_Bad_ID()
        {
            var user = new GenericUser("tal", new string[] { "Admin" });
            ((TestUser)ObjectFactory.GetInstance<IUser>()).SetUser(user);
            MyAlbum.Services.SectionService target = this.Service;
            MyAlbum.Model.Section item = new Section()
            {
                ContentUrl = Guid.NewGuid().ToString(),
                Name = Guid.NewGuid().ToString(),
                Visible = true,
                Description = Guid.NewGuid().ToString()
            };
            target.AddItem(item, new MyAlbum.Utility.GenericValidationSummary());
            this.sections.Add(item);
            var loaded = target.GetItemById(item.Id + 1);
            Assert.IsNull(loaded);
        }

        /// <summary>
        ///A test for DeleteItem
        ///</summary>
        [TestMethod()]
        public void DeleteItemTest()
        {
            var user = new GenericUser("tal", new string[] { "Admin" });
            ((TestUser)ObjectFactory.GetInstance<IUser>()).SetUser(user);
            MyAlbum.Services.SectionService target = this.Service;
            MyAlbum.Model.Section item = new Section()
            {
                ContentUrl = Guid.NewGuid().ToString(),
                Name = Guid.NewGuid().ToString(),
                Visible = true,
                Description = Guid.NewGuid().ToString()
            };
            target.AddItem(item, new MyAlbum.Utility.GenericValidationSummary());
            this.sections.Add(item);

            MyAlbum.Model.Section item2 = new Section()
            {
                ContentUrl = Guid.NewGuid().ToString(),
                Name = Guid.NewGuid().ToString(),
                Visible = true,
                Description = Guid.NewGuid().ToString()
            };
            target.AddItem(item2, new MyAlbum.Utility.GenericValidationSummary());
            this.sections.Add(item2);


            var loaded = target.GetItemById(item.Id);
            Assert.IsNotNull(loaded);
            target.DeleteItem(item);
            loaded = target.GetItemById(item.Id);
            Assert.IsNull(loaded);
            Assert.IsNotNull(target.GetItemById(item2.Id));
        }


        [TestMethod()]
        public void DeleteItemTest_Non_Admin()
        {
            var user = new GenericUser("tal", new string[] { "Admin" });
            ((TestUser)ObjectFactory.GetInstance<IUser>()).SetUser(user);
            MyAlbum.Services.SectionService target = this.Service;
            MyAlbum.Model.Section item = new Section()
            {
                ContentUrl = Guid.NewGuid().ToString(),
                Name = Guid.NewGuid().ToString(),
                Visible = true,
                Description = Guid.NewGuid().ToString()
            };
            target.AddItem(item, new MyAlbum.Utility.GenericValidationSummary());
            this.sections.Add(item);

            MyAlbum.Model.Section item2 = new Section()
            {
                ContentUrl = Guid.NewGuid().ToString(),
                Name = Guid.NewGuid().ToString(),
                Visible = true,
                Description = Guid.NewGuid().ToString()
            };
            target.AddItem(item2, new MyAlbum.Utility.GenericValidationSummary());
            this.sections.Add(item2);


            var loaded = target.GetItemById(item.Id);
            Assert.IsNotNull(loaded);
            user = new GenericUser("tal", new string[] { "User" });
            ((TestUser)ObjectFactory.GetInstance<IUser>()).SetUser(user);
            target.DeleteItem(item);
            loaded = target.GetItemById(item.Id);
            Assert.IsNotNull(loaded);
            Assert.IsNotNull(target.GetItemById(item2.Id));
        }
        /// <summary>
        ///A test for UpdateItem
        ///</summary>
        [TestMethod()]
        public void AddItemTest()
        {
            var user = new GenericUser("tal", new string[] { "Admin" });
            ((TestUser)ObjectFactory.GetInstance<IUser>()).SetUser(user);
            MyAlbum.Services.SectionService target = this.Service;
            MyAlbum.Model.Section item = new Section()
            {
                ContentUrl = Guid.NewGuid().ToString(),
                Name = Guid.NewGuid().ToString(),
                Description = Guid.NewGuid().ToString()
            };
            target.AddItem(item, new MyAlbum.Utility.GenericValidationSummary());
            this.sections.Add(item);
            var loaded = target.GetItemById(item.Id);
            Assert.IsNotNull(loaded);
            Compare(item, loaded);
        }

        [TestMethod()]
        public void AddItemTest_Authorized_User()
        {
            var user = new GenericUser("tal", new string[] { RolesManager.AddItemsRoles });
            ((TestUser)ObjectFactory.GetInstance<IUser>()).SetUser(user);
            MyAlbum.Services.SectionService target = this.Service;
            MyAlbum.Model.Section item = new Section()
            {
                ContentUrl = Guid.NewGuid().ToString(),
                Name = Guid.NewGuid().ToString(),
                Description = Guid.NewGuid().ToString()
            };
            target.AddItem(item, new MyAlbum.Utility.GenericValidationSummary());
            this.sections.Add(item);
            var loaded = target.GetItemById(item.Id);
            Assert.IsNotNull(loaded);
            Compare(item, loaded);
        }

        [TestMethod()]
        public void AddItemTest_Un_Authorized_User()
        {
            var user = new GenericUser("tal", new string[] { "User" });
            ((TestUser)ObjectFactory.GetInstance<IUser>()).SetUser(user);
            MyAlbum.Services.SectionService target = this.Service;
            MyAlbum.Model.Section item = new Section()
            {
                ContentUrl = Guid.NewGuid().ToString(),
                Name = Guid.NewGuid().ToString(),
                Description = Guid.NewGuid().ToString(),
                Visible = true
            };
            var v = new MyAlbum.Utility.GenericValidationSummary();
            target.AddItem(item, v);
            this.sections.Add(item);
            Assert.IsFalse(v.IsValid);
            Assert.AreEqual(0, item.Id);
            var loaded = target.GetItemById(item.Id);
            Assert.IsNull(loaded);
         
        }

        /// <summary>
        ///A test for UpdateItem
        ///</summary>
        [TestMethod()]

        public void AddItem_Null_Name()
        {
            var user = new GenericUser("tal", new string[] { "Admin" });
            ((TestUser)ObjectFactory.GetInstance<IUser>()).SetUser(user);
            MyAlbum.Services.SectionService target = this.Service;
            MyAlbum.Model.Section item = new Section()
            {
                ContentUrl = Guid.NewGuid().ToString(),
                Description = Guid.NewGuid().ToString()
            };
            var v = new MyAlbum.Utility.GenericValidationSummary();
            target.AddItem(item, v);
            this.sections.Add(item);
            Assert.IsFalse(v.IsValid);
            Assert.AreEqual("Name", v.Errors.Keys.First());
            Assert.AreEqual(0, item.Id);
        }

        /// <summary>
        ///A test for UpdateItem
        ///</summary>
        [TestMethod()]
        public void AddItem_Empty_Name()
        {
            var user = new GenericUser("tal", new string[] { "Admin" });
            ((TestUser)ObjectFactory.GetInstance<IUser>()).SetUser(user);
            MyAlbum.Services.SectionService target = this.Service;
            MyAlbum.Model.Section item = new Section()
            {
                ContentUrl = Guid.NewGuid().ToString(),
                Name = " ",
                Description = Guid.NewGuid().ToString()
            };
            var v = new MyAlbum.Utility.GenericValidationSummary();
            target.AddItem(item, v);
            this.sections.Add(item);
            Assert.IsFalse(v.IsValid);
            Assert.AreEqual("Name", v.Errors.Keys.First());
            Assert.AreEqual(0, item.Id);
        }

        /// <summary>
        ///A test for UpdateItem
        ///</summary>
        [TestMethod()]
        [ExpectedException(typeof(AssertionException))]
        public void AddItem_Null_Item()
        {
            var user = new GenericUser("tal", new string[] { "Admin" });
            ((TestUser)ObjectFactory.GetInstance<IUser>()).SetUser(user);
            MyAlbum.Services.SectionService target = this.Service;
            target.AddItem(null, new MyAlbum.Utility.GenericValidationSummary());
        }
        /// <summary>
        ///A test for SectionService Constructor
        ///</summary>
        [TestMethod()]
        [ExpectedException(typeof(AssertionException))]
        public void SectionServiceConstructorTest()
        {
            MyAlbum.Data.ISectionRepository sectionRepository = null;
            MyAlbum.Services.SectionService target = new MyAlbum.Services.SectionService(sectionRepository, null, null);
        }
    }
}
